package com.atom.app.mvvm.stack

import android.app.Activity
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.format.DateUtils
import java.lang.ref.Reference
import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicBoolean

object AppStateManager {
    const val NOTICE: Int = 2048
    private val MIN_NOTICE_SECOND: Long = 5 * DateUtils.SECOND_IN_MILLIS
    private val handler: Handler
    private var mForegroundActivity: Reference<Activity?>? = null
    private val mListeners: MutableSet<AppStateListener> = HashSet()
    private val isAppShow = AtomicBoolean(false)
    private var minSecond = MIN_NOTICE_SECOND

    init {
        handler = object : Handler(Looper.getMainLooper()) {
            override fun handleMessage(msg: Message) {
                if (msg.what == NOTICE) {
                    notifyListeners(isAppShow)
                    return
                }
                super.handleMessage(msg)
            }
        }
    }

    fun setBackgroundNoticeSecond(second: Int) {
        var second = second
        if (second <= 0) {
            second = 5
        }
        minSecond = second * DateUtils.SECOND_IN_MILLIS
    }

    /**
     * 当 Activity 可见时应该调用这个方法
     */
    fun onActivityShow(activity: Activity?) {
        if (mForegroundActivity != null) {
            mForegroundActivity!!.clear()
        }
        mForegroundActivity = WeakReference<Activity?>(activity)
        determineAppForegroundState()
    }

    /**
     * 当 Activity 不再可见时应该调用这个方法
     */
    fun onActivityHide(activity: Activity?) {
        /*
         * 前台 Activity 可能会被一个新的 Activity 替换。
         * 如果新 Activity 与前台 Activity 匹配，仅仅清除前台 Activity
         */
        if (mForegroundActivity != null) {
            val ref = mForegroundActivity!!.get()
            if (activity === ref) {
                // This is the activity that is going away, clear the reference
                mForegroundActivity!!.clear()
                mForegroundActivity = null
            }
        }
        determineAppForegroundState()
    }


    /**
     * 用于判断应用是否处于前台
     */
    fun isAppInForeground(): Boolean {
        return isAppShow.get()
    }

    /**
     * 用于判断当前状态，更新追踪的目标，并通知所有观察者状态是否发生了改变
     */
    private fun determineAppForegroundState() {
        /* 决定当前状态 */
        val oldAppShow = isAppShow.get()
        /* 决定当前状态 */
        isAppShow.set(mForegroundActivity != null && mForegroundActivity!!.get() != null)
        /* 如果新的状态与之前的状态不一样，则之前的状态需要通知所有观察者状态发生了改变 */
        if (oldAppShow != isAppShow.get()) {
            validateThenNotifyListeners()
        }
    }

    /**
     * 添加用于监听前台应用状态的监听器
     */
    fun addListener(listener: AppStateListener?) {
        handler.post(Runnable { mListeners.add(listener!!) })
    }

    /**
     * 移除用于监听前台应用状态的监听器
     */
    fun removeListener(listener: AppStateListener?) {
        handler.post(Runnable { mListeners.remove(listener) })
    }


    fun clearListener() {
        handler.post(Runnable { mListeners.clear() })
    }

    /**
     * 通知所有监听器前台应用状态发生了改变
     */
    private fun notifyListeners(statue: AtomicBoolean) {
        val curr = statue.get()
        for (mListener in mListeners) {
            mListener.appState(curr)
        }
    }

    private fun validateThenNotifyListeners() {
        if (handler.hasMessages(NOTICE)) {
            handler.removeMessages(NOTICE)
        } else {
            if (isAppShow.get()) {
                handler.sendEmptyMessage(NOTICE)
            } else {
                handler.sendEmptyMessageDelayed(
                    NOTICE,
                    minSecond
                )
            }
        }
    }
}